package cn.wen.yinxiu.product.service.impl;

import cn.wen.yinxiu.common.convention.errorcode.ErrorCode;
import cn.wen.yinxiu.common.convention.exception.ServiceException;
import cn.wen.yinxiu.common.to.product.OrderItemTO;
import cn.wen.yinxiu.common.to.product.SkuLockTO;
import cn.wen.yinxiu.product.controller.SkuInfoController;
import cn.wen.yinxiu.product.entity.StockOrderTaskDetailEntity;
import cn.wen.yinxiu.product.entity.StockOrderTaskEntity;
import cn.wen.yinxiu.product.service.SkuInfoService;
import cn.wen.yinxiu.product.service.StockOrderTaskDetailService;
import cn.wen.yinxiu.product.service.StockOrderTaskService;
import cn.wen.yinxiu.product.vo.StockDetailVO;
import cn.wen.yinxiu.product.vo.StockLockedVO;
import org.checkerframework.checker.units.qual.A;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yinxiu.common.toolkit.PageUtils;
import cn.wen.yinxiu.common.toolkit.Query;

import cn.wen.yinxiu.product.dao.StockSkuDao;
import cn.wen.yinxiu.product.entity.StockSkuEntity;
import cn.wen.yinxiu.product.service.StockSkuService;
import org.springframework.transaction.annotation.Transactional;


@Service("stockSkuService")
public class StockSkuServiceImpl extends ServiceImpl<StockSkuDao, StockSkuEntity> implements StockSkuService {

    @Autowired
    private StockSkuDao stockSkuDao;

    @Autowired
    private StockOrderTaskService stockOrderTaskService;

    @Autowired
    private StockOrderTaskDetailService stockOrderTaskDetailService;

    @Autowired
    private RabbitTemplate rabbitTemplate;



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<StockSkuEntity> page = this.page(
                new Query<StockSkuEntity>().getPage(params),
                new QueryWrapper<StockSkuEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public boolean getSkuHasStock(Long skuId) {
        Long stockCount = stockSkuDao.getSkuStock(skuId);
        return stockCount > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean orderLockStock(SkuLockTO lockTO) {
        /**
         * 保存库存工作单详情信息
         * 追溯
         */
        StockOrderTaskEntity stockOrderTaskEntity = new StockOrderTaskEntity();
        stockOrderTaskEntity.setOrderSn(lockTO.getOrderSn());
        stockOrderTaskEntity.setCreateTime(new Date());
        stockOrderTaskService.save(stockOrderTaskEntity);


        // 1、按照下单的收货地址，找到一个就近仓库，锁定库存（这里不需要找到仓库  直接购买）
        // 2、找到每个商品在哪个仓库都有库存
        OrderItemTO locks = lockTO.getLocks();

        Long skuId = locks.getSkuId();
        // 判断是否还存在库存
        Long stockNum = stockSkuDao.getSkuStock(skuId);

        // 2、锁定库存
        boolean skuStocked = false;

        if (stockNum <= 0) {
            // 没有任何仓库有这个商品的库存
            throw new ServiceException(ErrorCode.SKU_NO_STOCK);
        }

        // 1、如果每一个商品都锁定成功,将当前商品锁定了几件的工作单记录发给MQ
        // 2、锁定失败。前面保存的工作单信息都回滚了。发送出去的消息，即使要解锁库存，由于在数据库查不到指定的id，所有就不用解锁
        // 锁定成功就返回1，失败就返回0
        Long count = stockSkuDao.lockSkuStock(skuId, lockTO.getLocks().getCount());
        if (count == 1) {
            skuStocked = true;
            OrderItemTO orderItem = lockTO.getLocks();
            StockOrderTaskDetailEntity taskDetailEntity = StockOrderTaskDetailEntity.builder()
                    .skuId(skuId)
                    .skuName(orderItem.getTitle())
                    .skuNum(orderItem.getCount())
                    .taskId(stockOrderTaskEntity.getId())
                    .lockStatus(1)
                    .build();
            stockOrderTaskDetailService.save(taskDetailEntity);

            // TODO 告诉MQ库存锁定成功
            StockLockedVO lockedVO = new StockLockedVO();
            lockedVO.setId(stockOrderTaskEntity.getId());
            StockDetailVO detailVO = new StockDetailVO();
            BeanUtils.copyProperties(taskDetailEntity, detailVO);
            lockedVO.setDetailVO(detailVO);
            rabbitTemplate.convertAndSend("stock-event-exchange", "stock.locked", lockedVO);
        }

        if (skuStocked == false) {
            //当前商品所有仓库都没有锁住
            throw new ServiceException(ErrorCode.SKU_NO_STOCK);
        }

        //3、肯定全部都是锁定成功的
        return true;
    }

    @Override
    public void unLockStock(Long skuId, Integer num) {
        stockSkuDao.unLockStock(skuId, num);
    }

}